//Name: Sara Thorup
#include "dominion.h"
#include "dominion_helpers.h"
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include "rngs.h"

void test(int toFlag);
void setHandDeckDiscard(struct gameState* gameState, int testPlayer);

/*
Unit tests for  int gainCard(int supplyPos, struct gameState *state, int toFlag, int player)
gainCard() puts a card in a players hand, discard pile, or deck depending on the toFlag

Things to test:
- toFlag = 0: add to discard pile and increment count
- toFlag = 1: add deck and increment count
- toFlag = 2: add to hand and increment count
- decrease supply count of the card type
- test what happens when there is not enough of that card

*/
int main(int argc, char *argv[]) {
	printf("\n ===== Testing gainCard() =====\n");
	test(0);
	test(1);
	test(2);
	return 0;
}

void test(int toFlag) {
	if (toFlag == 0) {
		printf("\nGain card to discard pile \n");
	} else if (toFlag == 1) {
		printf("\nGain card to deck \n");
	} else if (toFlag == 2) {
		printf("\nGain card to hand \n");
	}
	//setup
	struct gameState* gameState = newGame();
	int testPlayer = 0;
	int numPlayers = 2;
	int testCard = 0;
	int kingdomCards[10] = {adventurer, council_room, feast, gardens, mine, remodel, smithy, village, baron, great_hall};
	int randomSeed = 10;
	if (initializeGame(numPlayers, kingdomCards, randomSeed, gameState) != 0){
		printf("Error initalizing game. \n");
		return;
	}
	setHandDeckDiscard(gameState, testPlayer);
	int initalHandCount = gameState->handCount[testPlayer];
	int initalDiscardCount = gameState->discardCount[testPlayer];
	int initalDeckCount = gameState->deckCount[testPlayer];
	int lastHandCard = gameState->hand[testPlayer][initalHandCount - 1];
	int lastDeckCard = gameState->deck[testPlayer][initalDeckCount - 1];
	int lastDiscardCard = gameState->discard[testPlayer][initalDiscardCount - 1];
	
	//test what happens when there is no more of the desired card
	gameState->supplyCount[testCard] = 0;
	int gainCardStatus = gainCard(testCard, gameState, toFlag, testPlayer);

	if (gainCardStatus == -1) {
		printf("gainCard(): PASS exiting with error when supply is empty \n");
	} else {
		printf("gainCard(): FAIL exiting with error when supply is empty\n");
	}

	if (toFlag == 0) {
		if (initalDiscardCount == gameState->discardCount[testPlayer]){
			printf("gainCard(): PASS discard count did not increase when supply is empty \n");
		} else {
			printf("gainCard(): FAIL discard count incraesed  when supply is empty \n");
		}

		if (lastDiscardCard == gameState->discard[testPlayer][initalDiscardCount - 1]) {
			printf("gainCard(): PASS no new card was added to discard deck when supply is empty \n");
		} else {
			printf("gainCard(): FAIL new card was added to discard deck when supply is empty \n");
		}
	}
	if (toFlag == 1) {

		if (initalDeckCount == gameState->deckCount[testPlayer]){
				printf("gainCard(): PASS deck count did not increase when supply is empty \n");
			} else {
				printf("gainCard(): FAIL deck count incraesed  when supply is empty \n");
			}

			if (lastDeckCard == gameState->deck[testPlayer][initalDeckCount - 1]) {
				printf("gainCard(): PASS no new card was added to deck when supply is empty \n");
			} else {
				printf("gainCard(): FAIL new card was added to deck when supply is empty \n");
			}
	}
	if (toFlag == 2){
		if (initalHandCount == gameState->handCount[testPlayer]){
				printf("gainCard(): PASS hand count did not increase when supply is empty \n");
		} else {
			printf("gainCard(): FAIL hand count incraesed  when supply is empty \n");
		}

		if (lastHandCard == gameState->hand[testPlayer][initalHandCount - 1]) {
			printf("gainCard(): PASS no new card was added to hand when supply is empty \n");
		} else {
			printf("gainCard(): FAIL new card was added to hand when supply is empty \n");
		}
	}

	//test when supply > 0
	gameState->supplyCount[testCard] = 10;
	int initalSupply = gameState->supplyCount[testCard];
	gainCardStatus = gainCard(testCard, gameState, toFlag, testPlayer);

	if (gainCardStatus == 0) {
		printf("gainCard(): PASS returned without error when supply was not empty \n");
	} else {
		printf("gainCard(): FAIL did not return without error when supply was not empty\n");
	}

	if (toFlag == 0) {
		if (gameState->discardCount[testPlayer] == initalDiscardCount + 1){
			printf("gainCard(): PASS discard count incremented when supply was not empty \n");
		} else {
			printf("gainCard(): FAIL discard count did not increment when supply was not empty \n");
		}
		if (gameState->discard[testPlayer][initalDiscardCount] == testCard) {
			printf("gainCard(): PASS desired card was added to discard pile \n");
		} else {
			printf("gainCard(): FAIL desired card was not added to discard pile \n");
		}

	}
	if (toFlag == 1) {
		if (gameState->deckCount[testPlayer] == initalDeckCount + 1){
			printf("gainCard(): PASS deck count incremented when supply was not empty \n");
		} else {
			printf("gainCard(): FAIL deck count did not increment when supply was not empty \n");
		}
		if (gameState->deck[testPlayer][initalDeckCount] == testCard) {
			printf("gainCard(): PASS desired card was added to deck pile \n");
		} else {
			printf("gainCard(): FAIL desired card was not added to deck pile \n");
		}

	}
	if (toFlag ==2) {
		if (gameState->handCount[testPlayer] == initalHandCount + 1){
			printf("gainCard(): PASS hand count incremented when supply was not empty \n");
		} else {
			printf("gainCard(): FAIL hand count did not increment when supply was not empty \n");
		}
		if (gameState->hand[testPlayer][initalHandCount] == testCard) {
			printf("gainCard(): PASS desired card was added to hand \n");
		} else {
			printf("gainCard(): FAIL desired card was not added to hand  \n");
		}

	}

	//test supply was changed
	if (gameState->supplyCount[testCard] == initalSupply - 1) {
		printf("gainCard(): PASS supply count was decremented after gaining card \n");
	} else {
		printf("gainCard(): FAIL supply count was not decremented after gaining card \n");
	}
	
}
void setHandDeckDiscard(struct gameState* gameState, int testPlayer) {
	gameState->handCount[testPlayer] = 3;
    gameState->discardCount[testPlayer] = 4;
    gameState->deckCount[testPlayer] = 5;

    int i = 0;

    for (; i < gameState->handCount[testPlayer]; i++) {
    	gameState->hand[testPlayer][i] = gold;
    }
   
   	for (i = 0; i < gameState->discardCount[testPlayer]; i++) {
   		gameState->discard[testPlayer][i] = gold;
   	}

   	for (i = 0; i < gameState->deckCount[testPlayer]; i++) {
   		gameState->deck[testPlayer][i] = gold;
   	}
}
